var http = require('http'),
inspect = require('util').inspect,
fs = require('fs'),
path = require('path'),
db = require('./db'),
async = require('async'),
utils = require('./utils');

var Busboy = require('busboy');

function execute(req, res) {
  var infiles = 0, outfiles = 0, done = false;
  var busboy = new Busboy({ headers: req.headers });
  var key, type, tmpfilename;
  console.log('Start parsing multipart request ...');
  busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
    ++infiles;
    tmpfilename = filename;
    onFile(req, fieldname, file, filename, function() {
      ++outfiles;
      if (done)
        console.log(outfiles + '/' + infiles + ' parts written to disk');
      if (done && infiles === outfiles) {
        // ACTUAL EXIT CONDITION
        console.log('All parts written to disk');
      }
    });
  });
  busboy.on('field', function(fieldname, val, valTruncated, keyTruncated) {
    if (fieldname == 'key') {
      key = val;
    } else if (fieldname == 'type') {
      type = val;
    }
    console.log('Field [' + fieldname + ']: value: ' + inspect(val));
  });
  busboy.on('end', function() {
    console.log('Done parsing multipart request!');
    done = true;
    if (key && typeof key !== 'undefined' &&
        type && typeof type !== 'undefined') {
        var oldpath = path.join(
            __dirname + '/tmp/',
            path.basename(req.user.id + tmpfilename)
        );
        var newdir = __dirname + '/audio/' + req.user.id;
        var newpath = path.join(newdir, path.basename(key + '.' + type));
        async.waterfall(
            [
                function(cb) {
                    fs.exists(newdir, function(exists) {
                        cb(null, exists);
                    });
                },
                function(exists, cb) {
                    if (!exists) {
                        fs.mkdir(path.join(newdir), cb);
                    } else {
                        cb(null)
                    }
                },
                async.apply(fs.rename, oldpath, newpath),
                async.apply(db.addKeyForUser, req.user.id, key)
            ],
            function(err) {
                if (err) {
                    utils.responseError(res, 400, err);
                } else { 
                    utils.responseSuccess(res);
                }           
            }
        );
    } 
  });
  req.pipe(busboy);
}

function onFile(req, fieldname, file, filename, next) {
  // or save at some other location
  var fstream = fs.createWriteStream(
    path.join(__dirname + '/tmp', path.basename(req.user.id + filename))
  );
  file.on('end', function() {
    console.log(fieldname + '(' + filename + ') EOF');
  });
  fstream.on('close', function() {
    console.log(fieldname + '(' + filename + ') written to disk');
    next();
  });
  console.log(fieldname + '(' + filename + ') start saving');
  file.pipe(fstream);
}

module.exports = {
  execute: execute
}
